#pragma once
#include "type_traits"
#include "utility"
#include "ParseFunction.h"
namespace Anger
{
	struct DelegateBase
	{
		virtual ~DelegateBase() = default;
		virtual void Call() = 0;
	};
	template<typename Callable, typename ...Args>
	struct DelegateCallable :DelegateBase
	{
		Callable callable;
		std::tuple<Args...>args;

		DelegateCallable(Callable callable_, Args...args_)
			:callable(callable_), args(args_...) {}

		virtual ~DelegateCallable() = default;
		void Call() override
		{
			apply(callable, args);
		}
	};
	
	template<class Class, typename Func, typename ...Args>
	struct DelegateMember :DelegateBase
	{
		using function = Func(Class::*)(Args...);
		function func;
		Class* instance;
		std::tuple<Args...>args;

		DelegateMember(function function, Class* inst, Args... args_)
			:func(function), instance(inst), args(args_...) {}

		virtual ~DelegateMember() = default;
		void Call() override
		{
			apply(instance, func, args);
		}
	};


}